package com.yungu.swift.assets.passenger.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yungu.swift.assets.passenger.dao.PassengerInvoiceLogMapper;
import com.yungu.swift.assets.passenger.dao.PassengerInvoiceMapper;
import com.yungu.swift.assets.passenger.model.dto.PassengerInvoiceDto;
import com.yungu.swift.assets.passenger.model.dto.PassengerInvoiceLogDto;
import com.yungu.swift.assets.passenger.model.param.AdminPassengerInvoicePageParam;
import com.yungu.swift.assets.passenger.model.param.AdminPassengerInvoiceParam;
import com.yungu.swift.assets.passenger.model.param.ApiPassengerInvoiceParam;
import com.yungu.swift.assets.passenger.model.vo.PassengerInvoiceAdminVo;
import com.yungu.swift.assets.passenger.service.PassengerInvoiceService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.service.impl.BaseServiceImpl;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.constants.PassengerConstant;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.service.OrderService;
import com.yungu.swift.system.finance.model.dto.FinanceActualFlowDto;
import com.yungu.swift.system.finance.service.FinanceActualFlowService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;


/**
 * 乘客发票业务逻辑处理接口实现类
 *
 * @author cuixiuyin - Generate
 * @version 1.1.1-SNAPSHOT
 * @since 2018-07-04 13:50
 */
@Slf4j
@Service
public class PassengerInvoiceServiceImpl extends BaseServiceImpl<PassengerInvoiceDto> implements PassengerInvoiceService {
    @Autowired
    private PassengerInvoiceMapper passengerInvoiceMapper;
    @Autowired
    private PassengerInvoiceLogMapper passengerInvoiceLogMapper;
    @Reference
    private OrderService orderService;
    @Reference
    private FinanceActualFlowService financeActualFlowService;

    @Override
    protected IMapper<PassengerInvoiceDto> getMapper() {
        return passengerInvoiceMapper;
    }

    @Override
    public ResponseData<PageVo<PassengerInvoiceAdminVo>> queryPageAdmin(AdminPassengerInvoicePageParam invoicePageParam) {
        PageBounds pageBounds = new PageBounds(invoicePageParam.getPageNum(), invoicePageParam.getPageSize());
        PageList<PassengerInvoiceAdminVo> pageList = passengerInvoiceMapper.queryPageAdmin(MapUtils.convertObjToMap(invoicePageParam), pageBounds);
        PageVo<PassengerInvoiceAdminVo> pageVo = new PageVo(invoicePageParam.getPageNum(), invoicePageParam.getPageSize(),
                pageList.getPaginator().getTotalCount());
        pageVo.setItems(pageList);
        return ResponseData.buildSuccessResponse(pageVo);
    }

    @Override
    public ResponseData<List<PassengerInvoiceAdminVo>> listExport(AdminPassengerInvoicePageParam invoicePageParam) {
        return ResponseData.buildSuccessResponse(passengerInvoiceMapper.listExport(MapUtils.convertObjToMap(invoicePageParam)));
    }


    @Override
    public ResponseData<PassengerInvoiceAdminVo> detail(String uuid) {
        List<PassengerInvoiceAdminVo> list = passengerInvoiceMapper.detail(uuid);
        if (CollectionUtils.isNotEmpty(list)) {
            return ResponseData.buildSuccessResponse(list.get(0));
        }
        return ResponseData.buildSuccessResponse(null);
    }

    @Override
    public ResponseData<Boolean> saveOrUpdate(AdminPassengerInvoiceParam passengerInvoiceParam) {
        PassengerInvoiceDto passengerInvoiceDto = new PassengerInvoiceDto();
        BeanUtils.copyProperties(passengerInvoiceParam, passengerInvoiceDto);
        passengerInvoiceDto.setUpdateOn(new Date());
        passengerInvoiceDto.setUpdateBy(passengerInvoiceParam.getUserUuid());
        if (passengerInvoiceMapper.edit(passengerInvoiceDto) > 0) {
            // 保存Log表
            insertInvoiceLog(passengerInvoiceDto.getUuid(), passengerInvoiceDto.getStatus(), passengerInvoiceParam.getRemark());
            // 更新订单发票状态
            updateInvoiceOrder(passengerInvoiceParam.getOrderUuid(), passengerInvoiceDto.getType(), passengerInvoiceParam.getStatus());
            return ResponseData.buildSuccessResponse("保存成功", Boolean.TRUE);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "保存失败");
    }

    @Override
    public ResponseData<PassengerInvoiceDto> billing(ApiPassengerInvoiceParam pasInvoiceParam) {
        PassengerInvoiceDto passengerInvoiceDto = new PassengerInvoiceDto();
        BeanUtils.copyProperties(pasInvoiceParam, passengerInvoiceDto);
        passengerInvoiceDto.setUuid(StringUtils.buildUUID());
        passengerInvoiceDto.setPassengerUuid(pasInvoiceParam.getUserUuid());
        passengerInvoiceDto.setStatus(0);
        passengerInvoiceDto.setCreateOn(new Date());
        passengerInvoiceDto.setOrderUuid(pasInvoiceParam.getOrderIds());
        //保存主表成功
        if (passengerInvoiceMapper.add(passengerInvoiceDto) > 0) {
            // 保存Log表
            insertInvoiceLog(passengerInvoiceDto.getUuid(), PassengerConstant.INVOICE_BILLING_APPLY, "提交申请");
            // 更新订单发票状态
            updateInvoiceOrder(pasInvoiceParam.getOrderIds(), passengerInvoiceDto.getType(), 0);
            return ResponseData.buildSuccessResponse("保存成功", passengerInvoiceDto);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "保存失败");
    }


    /**
     * 更新发票底下订单状态
     *
     * @param ids
     * @param type
     * @param status
     */
    private void updateInvoiceOrder(final String ids, final Integer type, final Integer status) {
        CompletableFuture.runAsync(() -> {
            if (OrderConstant.BILLING_BY_ROUTE == type) {
                //按照行程开票的话，找order表的订单，设置isBilled
                for (String id : org.springframework.util.StringUtils.commaDelimitedListToStringArray(ids)) {
                    OrderDto orderDto = new OrderDto();
                    orderDto.setUuid(id);
                    orderDto.setIsBilled(status);
                    orderService.edit(orderDto);
                }
            }
            if (OrderConstant.BILLING_BY_CHARGE == type) {
                //按照充值开票的话，找actualFlow表的订单，设置isBilled
                for (String id : org.springframework.util.StringUtils.commaDelimitedListToStringArray(ids)) {
                    FinanceActualFlowDto financeActualFlowDto = new FinanceActualFlowDto();
                    financeActualFlowDto.setUuid(id);
                    financeActualFlowDto.setIsBilled(status);
                    financeActualFlowService.edit(financeActualFlowDto);
                }
            }
        }).whenComplete((e, throwable) -> log.info("ids:{}, 更新订单状态成功", ids));
    }

    /**
     * 插入发票日志
     *
     * @param opetation
     * @param remark
     */
    private void insertInvoiceLog(final String invoiceUuid, final Integer opetation, final String remark) {
        CompletableFuture.runAsync(() -> {
            PassengerInvoiceLogDto passengerInvoiceLogDto = new PassengerInvoiceLogDto();
            passengerInvoiceLogDto.setUuid(StringUtils.buildUUID());
            passengerInvoiceLogDto.setOperation(opetation);
            passengerInvoiceLogDto.setOperationTime(new Date());
            passengerInvoiceLogDto.setRemark(remark);
            passengerInvoiceLogDto.setPassengerInvoiceUuid(invoiceUuid);
            passengerInvoiceLogMapper.add(passengerInvoiceLogDto);
        }).whenComplete((e, throwable) -> log.info("invoiceUuid:{}, 插入日志成功", invoiceUuid));
    }

}